package com.shijunhao.graduation.service.business.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shijunhao.graduation.domain.bean.Keyword;
import com.shijunhao.graduation.domain.dto.BusinessNoteDto;
import com.shijunhao.graduation.domain.entity.*;
import com.shijunhao.graduation.domain.vo.*;
import com.shijunhao.graduation.enums.TableName;
import com.shijunhao.graduation.exception.BusinessException;
import com.shijunhao.graduation.exception.SystemRuntimeException;
import com.shijunhao.graduation.mapper.BusinessNoteMapper;
import com.shijunhao.graduation.properties.RoleParams;
import com.shijunhao.graduation.service.business.*;
import com.shijunhao.graduation.service.system.ISystemFileInfoService;
import com.shijunhao.graduation.service.system.impl.BaseServiceImpl;
import com.shijunhao.graduation.utils.PageUtils;
import org.apache.commons.io.FileUtils;
import org.aspectj.util.FileUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author shijunhao
 * @since 2022-03-31
 */
@Service
public class BusinessNoteServiceImpl extends BaseServiceImpl<BusinessNoteMapper, BusinessNote> implements IBusinessNoteService {

    @Resource
    private ISystemFileInfoService systemFileInfoService;
    @Resource
    private IBusinessUserInfoService userInfoService;
    @Resource
    private IBusinessNoteDiscussService businessNoteDiscussService;
    @Resource
    private IBusinessHotInfoService hotInfoService;
    @Resource
    private SimilarAnalyzer similarAnalyzer;
    @Resource
    private IBusinessConnectService businessConnectService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long insert(BusinessNoteDto dto) {
        BusinessNote entity = new BusinessNote();
        entity.setType(1);
        SystemFileInfo fileInfo = systemFileInfoService.upload(dto.getContent());
        BeanUtils.copyProperties(dto, entity);
        entity.setFileId(fileInfo.getId());
        //添加关键词信息
        List<Keyword> analyze = similarAnalyzer.analyze(dto.toString(), 5);
        entity.setKeywords(JSON.toJSONString(analyze));
        insertOne(entity);
        //插入热度信息
        hotInfoService.insertDefaultHotInfo(TableName.BUSINESS_NOTE.getLabel(), entity.getId());
        return entity.getId();
    }

    @Override
    public boolean update(BusinessNoteDto dto) {
        //判断是否是管理员或该评论的文章或论坛作者是否为本人
        CurrentUserVo user = userInfoService.getCurrentOrgUser();
        BusinessNote note = getById(dto.getId());
        if (!note.getCreateBy().equals(user.getUser().getId()) && !RoleParams.ADMIN.equals(user.getRole())) {
            throw new BusinessException("无修改权限");
        } else {
            //拷贝更新后的内容
            File file = systemFileInfoService.getFile(note.getFileId());
            try {
                FileUtils.write(file, dto.getContent(), StandardCharsets.UTF_8);
            } catch (IOException e) {
                throw new SystemRuntimeException("系统异常!");
            }
            //拷贝其他信息
            BeanUtils.copyProperties(dto, note);
            List<Keyword> analyze = similarAnalyzer.analyze(dto.toString(), 10);
            note.setKeywords(JSON.toJSONString(analyze));
            return super.updateById(note);
        }
    }

    @Override
    public BusinessNoteVo mapping(BusinessNote note) {
        BusinessNoteVo businessNoteVo = new BusinessNoteVo();
        //获取简表信息
        BusinessNoteListVo simple = listVoMapping(note);
        //复制简表信息
        //获取用户详细信息
        businessNoteVo.setUserInfo(simple.getUserInfo());
        businessNoteVo.setNote(note);
        //获取热度信息
        businessNoteVo.setHotInfo(simple.getHotInfo());
        //获取内容
        try {
            businessNoteVo.setContent(FileUtil.readAsString(systemFileInfoService.getFile(note.getFileId())));
        } catch (IOException e) {
            e.printStackTrace();
        }
        //获取评论信息
        Page<DiscussVo> discuss = (Page<DiscussVo>) businessNoteDiscussService.page(PageUtils.initPage(), note.getId());
        businessNoteVo.setDiscussVoPage(discuss);
        return businessNoteVo;
    }

    @Override
    public BusinessNoteListVo listVoMapping(BusinessNote note) {
        BusinessNoteListVo vo = new BusinessNoteListVo();
        vo.setNote(note);
        //获取用户详细信息
        BusinessUserInfo userInfo = userInfoService.getOne(Wrappers.lambdaQuery(BusinessUserInfo.class).eq(BusinessUserInfo::getUid, note.getCreateBy()));
        vo.setUserInfo(userInfo);
        //获取热度信息
        BusinessHotInfo info = hotInfoService.getHotInfo(TableName.BUSINESS_NOTE.getLabel(), note.getId());
        vo.setHotInfo(info);
        //获取评论数
        int count = businessNoteDiscussService.selectCount(Wrappers.lambdaQuery(BusinessNoteDiscuss.class).eq(BusinessNoteDiscuss::getNid, note.getId()));
        vo.setDiscussCount(count);
        return vo;
    }

    @Override
    public Page<BusinessNoteListVo> pageList(IPage<BusinessNote> page, Wrapper<BusinessNote> wrapper) {
        Page<BusinessNote> result = this.page(page, wrapper);
        return (Page<BusinessNoteListVo>) result.convert(this::listVoMapping);
    }

    @Override
    public Page<BusinessNoteListVo> pageNew(IPage<BusinessNote> page) {
        return pageList(page, Wrappers.lambdaQuery(BusinessNote.class).eq(BusinessNote::getType, 1)
                .orderBy(true, true, BaseEntity::getCreateDate));
    }

    @Override
    public Page<BusinessNoteListVo> pageMine(IPage<BusinessNote> page,LambdaQueryWrapper<BusinessNote> wrapper) {
        CurrentUserVo user = userInfoService.getCurrentOrgUser();
        if (RoleParams.ADMIN.equals(user.getRole())) {
            return this.pageList(page, wrapper);
        } else {
            Page<BusinessNote> result = this.page(page, wrapper.eq(BaseEntity::getCreateBy, user.getUser().getId()));
            return (Page<BusinessNoteListVo>) result.convert(this::listVoMapping);
        }

    }

    @Override
    public boolean delete(Long id) {
        //判断是否是管理员或该评论的文章或论坛作者是否为本人
        CurrentUserVo user = userInfoService.getCurrentOrgUser();
        BusinessNote note = getById(id);
        if (!note.getCreateBy().equals(user.getUser().getId()) && !RoleParams.ADMIN.equals(user.getRole())) {
            throw new BusinessException("无删除权限");
        } else {
            return super.deleteById(id);
        }
    }

    @Override
    public SimpleNoteInfoVo toSimpleInfo(BusinessNote entity) {
        SimpleNoteInfoVo result = new SimpleNoteInfoVo();
        BeanUtils.copyProperties(entity, result);
        //获取内容
        try {
            result.setContent(FileUtil.readAsString(systemFileInfoService.getFile(entity.getFileId())));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    @Override
    public Page<BusinessNoteListVo> pageSuggest(Long id) {
        List<BusinessConnect> connects = businessConnectService.listByCondition(Wrappers.lambdaQuery(BusinessConnect.class).eq(BusinessConnect::getOriginalId, id));
        List<BusinessNote> businessNotes = listByIds(connects.stream().map(BusinessConnect::getTargetId).collect(Collectors.toList()));

        List<BusinessNoteListVo> result = new ArrayList<>();
        businessNotes.forEach(note -> result.add(this.listVoMapping(note)));
        return PageUtils.getPage(result);
    }
}
